package com.weiou.temperaturedemo;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.widget.AppCompatTextView;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.weiou.lib_temp.ReportBean;
import com.weiou.lib_temp.TempBle;
import com.weiou.lib_temp.TempBleCallback;

import java.util.List;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.rxjava3.core.Observable;


public class MainActivity extends BaseActivity
        implements DeviceAdapter.DeviceCallback, TempBleCallback {

    @BindView(R.id.recyclerView)
    RecyclerView recyclerView;
    @BindView(R.id.tvDeviceMessage)
    AppCompatTextView tvDeviceMessage;
    @BindView(R.id.tvTemp)
    AppCompatTextView tvTemp;
    @BindView(R.id.tvSetting)
    AppCompatTextView tvSetting;
    @BindView(R.id.tvHistory)
    TextView tvHistory;

    private TempBle tempBle;
    private String TAG = "MainActivity";
    private DeviceAdapter adapter;
    private MainViewModel model;
    private String unit = "";
    private String currentMac;
    //扫描回调
    private ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            if (result.getDevice() != null
                    && !TextUtils.isEmpty(result.getDevice().getName())) {
                Log.e(TAG, "onScanResult: " + result.getDevice().getName() + " ," + result.getDevice().getAddress());
                adapter.addDevice(result.getDevice());
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ButterKnife.bind(this);

        //实例化对象
        tempBle = new TempBle(BluetoothAdapter.getDefaultAdapter(), this);

        //ViewModel
        model = new ViewModelProvider(this).get(MainViewModel.class);

        initRecyclerView();
    }

    private void initRecyclerView() {
        adapter = new DeviceAdapter(this);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void onItemClick(String mac) {
        //停止扫描
        tempBle.stopScan(scanCallback);
        //断开连接
        tempBle.disconnect();
        //连接设备
        tempBle.connectBle(mac);
    }

    /**
     * ble连接成功
     *
     * @param address ble mac地址
     * @param name    ble 名字
     */
    @Override
    public void onConnectSuccess(String address, String name) {
        this.currentMac = address;
        adapter.updateStatus(address);
    }

    /**
     * ble断开连接
     */
    @Override
    public void onDisconnect() {
        runOnUiThread(() -> {
            adapter.disconnect();
            Toast.makeText(MainActivity.this, "BLE disconnected", Toast.LENGTH_SHORT).show();
        });
        this.currentMac = "";
    }

    /**
     * @param model 当前额温枪模式
     *              DataSendUtils.MODE_SURFACE
     *              DataSendUtils.MODE_ADULT
     *              DataSendUtils.MODE_CHILD
     * @param temp  额温枪返回温度
     */
    @Override
    public void onTempGet(int model, double temp) {
        this.model.setTemp(model, temp, tvTemp);
    }

    /**
     * 当前额温枪设备含有的模式
     *
     * @param bit0 表面模式    0为不含 1为含有
     * @param bit1 成人模式    0为不含 1为含有
     * @param bit2 儿童模式    0为不含 1为含有
     * @param bit3 是否NFC数据 0为蓝牙数据 1为NFC数据
     */
    @Override
    public void onDeviceMessageGet(Integer bit0, Integer bit1, Integer bit2, Integer bit3) {
        model.setDeviceMessage(bit0, bit1, bit2, tvDeviceMessage);
    }

    /**
     * 设备休眠
     */
    @Override
    public void onOffline() {
        runOnUiThread(() -> Toast.makeText(MainActivity.this, "Device is offline", Toast.LENGTH_SHORT).show());
    }

    /**
     * @param unit      "00"为摄氏度    "01"为华氏度
     * @param offset    偏移值
     * @param warmTemp  警告温度
     * @param funBool   蜂鸣器开关      "00"为开   "01"为关
     * @param sleepTime 休眠时间
     */
    @Override
    public void onSettingGet(String unit, double offset, double warmTemp, String funBool, int sleepTime) {
        model.setSetting(unit, offset, warmTemp, funBool, sleepTime, tvSetting);
        this.unit = unit;
    }

    @Override
    public void onDeviceOffline() {
        runOnUiThread(() -> Toast.makeText(MainActivity.this, R.string.wake_up1, Toast.LENGTH_SHORT).show());
    }

    /**
     * 移除方法
     */
    @Deprecated
    @Override
    public void onHistoryGet(List<ReportBean> list) {

    }

    /**
     * 设备被唤醒
     */
    @Override
    public void onWakeUp() {
        runOnUiThread(() -> Toast.makeText(MainActivity.this, R.string.wake_up, Toast.LENGTH_SHORT).show());
    }

    /**
     * 蓝牙异常代码返回
     *
     * @param i 详情https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-cts-5.1_r17/stack/include/gatt_api.h
     */
    @Override
    public void onGATTErr(int i) {
        runOnUiThread(() -> {
            Log.e(TAG, "onGATTErr: ");
            adapter.disconnect();
            Observable.timer(2000, TimeUnit.MILLISECONDS)
                    .subscribe(aLong -> {
                        if (!TextUtils.isEmpty(currentMac)) {
                            tempBle.connectBle(currentMac);
                        }
                    });
        });
    }

    /**
     * 获取NFC返回数据
     *
     * @param cardType 卡类型
     * @param cardSize 卡号长度
     * @param cardNo   卡号
     * @param target   00：表面模式
     *                 01：成人模式
     *                 02：儿童模式
     * @param temp     温度
     * @param unit     00: 摄氏度
     *                 01：华氏度
     */
    @Override
    public void onNFCGet(String cardType, int cardSize, String cardNo, String target, double temp, String unit) {
        runOnUiThread(() -> {
            String stringBuilder = "卡类型:" +
                    cardType +
                    "\n" +
                    "卡长度:" +
                    cardSize +
                    "\n" +
                    "target:" +
                    target +
                    "\n" +
                    "cardNo:" +
                    cardNo +
                    "\n" +
                    "unit:" +
                    temp +
                    "\n" +
                    "unit:" +
                    unit;
            Toast.makeText(MainActivity.this, stringBuilder, Toast.LENGTH_SHORT).show();
        });
    }

    //蓝牙设备服务信息
    @Override
    public void onServicesDiscovered(List<BluetoothGattService> list) {

    }

    /**
     * 蓝牙设备通知状态改变
     *
     * @param b true为打开
     */
    @Override
    public void onNotifyStatusChange(boolean b) {
        Log.e(TAG, b ? "Open notification" : "Close notification");
    }

    //gatt空指针(连接过程)
    @Override
    public void onGATTNull() {
        Log.e(TAG, "GATT is empty");
    }

    //Characteristic空指针(连接过程)
    @Override
    public void onCharacteristicNull() {
        Log.e(TAG, "Characteristic is empty");
    }

    //写入成功或者失败
    @Override
    public void onWriteStatusGet(boolean b) {
        Log.e(TAG, b ? "Sent successfully" : "Failed to send");
    }

    //ble正在连接
    @Override
    public void onConnecting() {
        Log.e(TAG, "onConnecting: ");
    }

    //*** 点击事件 *******************************************************************
    @OnClick({R.id.btnScan, R.id.btnStopScan})
    public void blueToothAction(View view) {
        switch (view.getId()) {
            case R.id.btnScan:
                tempBle.startScan(scanCallback);
                break;
            case R.id.btnStopScan:
                tempBle.stopScan(scanCallback);
                break;
        }
    }

    @OnClick({R.id.btnGetDeviceMessage, R.id.btnGetSetting})
    public void getMessage(View view) {
        switch (view.getId()) {
            case R.id.btnGetDeviceMessage:
                tempBle.getDeviceMessage();
                break;
            case R.id.btnGetSetting:
                tempBle.getDeviceConfig();
                break;
        }
    }

    @OnClick({R.id.btnChangeC, R.id.btnChangeF, R.id.btnOpenBuzzer, R.id.btnCloseBuzzer
            , R.id.btnOnOffDown, R.id.btnOnOffUp,
            R.id.btnTempDown, R.id.btnTempUp,
            R.id.btnOffsetDown, R.id.btnOffsetUp})
    public void setting(View view) {
        switch (view.getId()) {
            case R.id.btnChangeC:
                tempBle.setTempC();
                break;
            case R.id.btnChangeF:
                tempBle.setTempF();
                break;
            case R.id.btnOpenBuzzer:
                tempBle.openBuzzer();
                break;
            case R.id.btnCloseBuzzer:
                tempBle.closeBuzzer();
                break;
            case R.id.btnOnOffDown:
                tempBle.onOffDown();
                break;
            case R.id.btnOnOffUp:
                tempBle.onOffUp();
                break;
            case R.id.btnTempDown:
                if (TextUtils.isEmpty(unit)) {
                    Toast.makeText(this, "Please get device information first", Toast.LENGTH_SHORT).show();
                    return;
                }
                tempBle.tempDown(unit);
                break;
            case R.id.btnTempUp:
                if (TextUtils.isEmpty(unit)) {
                    Toast.makeText(this, "Please get device information first", Toast.LENGTH_SHORT).show();
                    return;
                }
                tempBle.tempUp(unit);
                break;
            case R.id.btnOffsetDown:
                if (TextUtils.isEmpty(unit)) {
                    Toast.makeText(this, "Please get device information first", Toast.LENGTH_SHORT).show();
                    return;
                }
                tempBle.offsetDown(unit);
                break;
            case R.id.btnOffsetUp:
                if (TextUtils.isEmpty(unit)) {
                    Toast.makeText(this, "Please get device information first", Toast.LENGTH_SHORT).show();
                    return;
                }
                tempBle.offsetUp(unit);
                break;
        }
    }
}
